package org.folio.rest.impl;

import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.Handler;
import io.vertx.core.json.Json;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import org.folio.rest.impl.other.PartyLogSave;
import org.folio.rest.impl.other.PartyUtil;
import org.folio.rest.jaxrs.model.Errors;
import org.folio.rest.jaxrs.model.PartySetCollection;
import org.folio.rest.jaxrs.model.PartySetGroup;
import org.folio.rest.persist.PgUtil;
import org.folio.rest.persist.PostgresClient;
import org.folio.rest.persist.cql.CQLWrapper;
import org.folio.rest.tools.utils.ValidationHelper;

import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static io.vertx.core.Future.succeededFuture;

/**
 * @author lee
 * @Classname PartySetImpl
 * @Description TODO
 * @Date 2020/6/18 16:41
 * @Created by lee
 */
public class PartySetImpl implements org.folio.rest.jaxrs.resource.PartySet {
    private final Logger logger = LoggerFactory.getLogger("modparty");

    private static final String NOTIFY_TABLE = "party_set";
    private static final String LOCATION_PREFIX = "/party/party_set";


    @Override
    public void postPartySet(String lang, org.folio.rest.jaxrs.model.PartySet entity, Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
        logger.debug("POST PartySet " + entity.getId() + " " + Json.encode(entity));
        String id = entity.getId();
        if (id == null || id.trim().isEmpty()) {
            id = UUID.randomUUID().toString();
        }
        entity.setIsDel(0);
        PostgresClient pg = PgUtil.postgresClient(vertxContext, okapiHeaders);
        pg.save(NOTIFY_TABLE,id,entity, reply->{
            String ret = reply.result();
            entity.setId(ret);

            asyncResultHandler.handle(succeededFuture(PostPartySetResponse
                    .respond201WithApplicationJson(entity, PostPartySetResponse.
                            headersFor201().withLocation(LOCATION_PREFIX + ret))));
            PartyLogSave.saveLog("新增【"+entity.getName()+"】系统配置",2, entity.getMetadata(),entity.getOperator(),okapiHeaders,asyncResultHandler,pg);
        });
    }


    @Override
    public void getPartySet(String query, int offset, int limit, String lang, Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
        CQLWrapper cql = null;
        try {
            cql = PartyUtil.getCQL(query, limit, offset,NOTIFY_TABLE);

        } catch (Exception e) {
            ValidationHelper.handleError(e, asyncResultHandler);
            return;
        }
        PgUtil.postgresClient(vertxContext, okapiHeaders)
                .get(NOTIFY_TABLE, org.folio.rest.jaxrs.model.PartySetGroup.class, new String[]{"*"}, cql,
                        true , false ,
                        reply -> {
                            if (reply.succeeded()) {
                                PartySetCollection notes = new PartySetCollection();
                                @SuppressWarnings("unchecked")
                                List<PartySetGroup> notifylist
                                        = reply.result().getResults();
                                notes.setPartySetGroup(notifylist);
                                Integer totalRecords = reply.result().getResultInfo().getTotalRecords();
                                notes.setTotalRecords(totalRecords);
                                asyncResultHandler.handle(succeededFuture(
                                        GetPartySetResponse.respond200WithApplicationJson(notes)));
                            } else {
                                ValidationHelper.handleError(reply.cause(), asyncResultHandler);
                            }
                        });
    }


    @Override
    public void getPartySetById(String id, String lang, Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {

        String noteId = id;
        if (noteId == null ) {
            logger.error("The id is NULL , check your request id" );
            Errors valErr = ValidationHelper.createValidationErrorMessage("id", noteId,
                    "Your request ID is empty, this is not allowed  ");
            asyncResultHandler.handle(succeededFuture(GetPartySetByIdResponse.respond404WithTextPlain(valErr)));
            return;
        }
        PgUtil.postgresClient(vertxContext, okapiHeaders)
                .getById(NOTIFY_TABLE,id,org.folio.rest.jaxrs.model.PartySet.class,callback->{
                    if (callback.failed()) {
                        ValidationHelper.handleError(callback.cause(), asyncResultHandler);
                        return;
                    }
                    if (callback.result() == null) {
                        asyncResultHandler.handle(succeededFuture(GetPartySetByIdResponse.respond404WithTextPlain(id)));
                        return;
                    }
                    asyncResultHandler.handle(succeededFuture(GetPartySetByIdResponse.respond200WithApplicationJson(callback.result())));
                });
    }


    @Override
    public void deletePartySetById(String id, String lang, Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
        logger.debug("DELETE PartySet " + id );
        String noteId = id;
        if (noteId == null ) {
            logger.error("The id is null , check your request id" );
            Errors valErr = ValidationHelper.createValidationErrorMessage("id", noteId,
                    "Your request Id is empty, this is not allowed  ");
            asyncResultHandler.handle(succeededFuture(DeletePartySetByIdResponse.respond404WithTextPlain(valErr)));
            return;
        }
        PostgresClient postgresClient = PgUtil.postgresClient(vertxContext, okapiHeaders);
        postgresClient.delete(NOTIFY_TABLE,id,reply->{
            if (reply.succeeded()) {
                if (reply.result().getUpdated() == 0) {
                    asyncResultHandler.handle(succeededFuture(DeletePartySetByIdResponse
                            .respond404WithTextPlain(id)));
                } else {
                    asyncResultHandler.handle(succeededFuture(
                            DeletePartySetByIdResponse.respond204()));

                    PartyLogSave.saveLog("删除【"+id+"】系统配置",4,null,okapiHeaders,asyncResultHandler,postgresClient);
                }

            } else {
                ValidationHelper.handleError(reply.cause(), asyncResultHandler);
                return;
            }
        });
    }

 
    @Override
    public void putPartySetById(String id, String lang, org.folio.rest.jaxrs.model.PartySet entity, Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
        logger.debug("PUT PartySet " + id + " " + Json.encode(entity));
        String noteId = entity.getId();
        if (noteId != null && !noteId.equals(id)) {
            logger.error("Trying to change note Id from " + id + " to " + noteId);
            Errors valErr = ValidationHelper.createValidationErrorMessage("id", noteId,
                    "Can not change the id");
            asyncResultHandler.handle(succeededFuture(PutPartySetByIdResponse.respond404WithTextPlain(valErr)));
            return;
        }
        PostgresClient pg = PgUtil.postgresClient(vertxContext, okapiHeaders);
        pg.update(NOTIFY_TABLE, entity, id,
                        reply -> {
                            if (reply.succeeded()) {
                                if (reply.result().getUpdated() == 0) {
                                    asyncResultHandler.handle(succeededFuture(PutPartySetByIdResponse
                                            .respond404WithTextPlain(id)));
                                } else { // all ok
                                    asyncResultHandler.handle(succeededFuture(
                                            PutPartySetByIdResponse.respond204()));
                                    PartyLogSave.saveLog("修改【"+entity.getName()+"】系统配置",3, entity.getMetadata(),entity.getOperator(),okapiHeaders,asyncResultHandler,pg);
                                }
                            } else {
                                ValidationHelper.handleError(reply.cause(), asyncResultHandler);
                            }
                        });
    }
}
